package com.vueblog.webapi.shiro;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author lsj
 * @create 2021-05-27 23:05
 */
@Configuration
public class ShiroConfig {
    //当前用户 第三步
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        // 设置安全管理器
        bean.setSecurityManager(defaultWebSecurityManager);
        /*
            authc：所有已登陆用户可访问
            user: 必须拥有 记住我 功能才能使用
            roles：有指定角色的用户可访问，通过[ ]指定具体角色，这里的角色名称与数据库中配置一致
            perms：有指定权限的用户可访问，通过[ ]指定具体权限，这里的权限名称与数据库中配置一致
            anon：所有用户可访问，通常作为指定页面的静态资源时使用
         */
        // 拦截
        Map<String, String> filterMap = new LinkedHashMap<>();
        filterMap.put("/admin/loginto", "anon");
        filterMap.put("/admin/login", "anon");
        filterMap.put("/admin/**", "authc");
        bean.setFilterChainDefinitionMap(filterMap);

        // 认证失败、未认证(即如上的请求被拦截时，跳转如下) 设置登录请求
        bean.setLoginUrl("/admin/loginto");

        return bean;
    }

    //安全管理器 第二步
    @Bean(name="securityManager")
    public DefaultWebSecurityManager getSecurityManager(@Qualifier("userRealm") MyRealm myRealm){
        DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();
        securityManager.setRealm(myRealm);
        return  securityManager;
    }
    //获取安全数据 第一步
    @Bean(name="userRealm")
    public MyRealm getRealm(){
        MyRealm myRealm = new MyRealm();
        //修改凭证校验匹配器
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        //设置加密算法为md5
        credentialsMatcher.setHashAlgorithmName("MD5");
        myRealm.setCredentialsMatcher(credentialsMatcher);
        return myRealm;
    }
}
